package com.ciei.dpagm.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ciei.dpagm.common.enums.DriverLibraryConfigTypeEnum;
import com.ciei.dpagm.common.enums.ErrorCodeEnum;
import com.ciei.dpagm.common.service.BaseService;
import com.ciei.dpagm.entity.DriverLibraryConfig;
import com.ciei.dpagm.entity.DriverLibraryDirectory;
import com.ciei.dpagm.mapper.DriverLibraryConfigMapper;
import com.ciei.dpagm.util.APP;
import com.ciei.dpagm.util.JsonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author wangyan
 * @date 2023/05/08
 */
@Service
public class DriverLibraryConfigService extends BaseService<DriverLibraryConfigMapper, DriverLibraryConfig> {

    @Lazy
    @Autowired
    private DriverLibraryDirectoryService driverLibraryDirectoryService;

    /**
     * 加载配置工程配置
     * @param query
     * @return
     */
    public JSONObject loadConfig(JSONObject query){
        Integer driverLibraryId = query.getInteger("driverLibraryId");
        JSONObject resultData = new JSONObject();
        List<DriverLibraryConfig> configList = findByProperty(DriverLibraryConfig::getDriverLibraryId,driverLibraryId);
        Set<Integer> directoryIds = configList.stream().map(DriverLibraryConfig::getDirectoryId).collect(Collectors.toSet());
        List<DriverLibraryDirectory> directoryList = driverLibraryDirectoryService.findListByIds(directoryIds);
        List<DriverLibraryConfig> hHeaderFileList = configList.stream().filter(e -> DriverLibraryConfigTypeEnum.H_HEADER.getId().equals(e.getType())).collect(Collectors.toList());
        JSONArray hHeaderFile = packageConfigData(hHeaderFileList,directoryList);
        List<DriverLibraryConfig> cSourceFileList = configList.stream().filter(e -> DriverLibraryConfigTypeEnum.C_SOURCE.getId().equals(e.getType())).collect(Collectors.toList());
        JSONArray cSourceFile = packageConfigData(cSourceFileList,directoryList);
        List<DriverLibraryConfig> templateFileList = configList.stream().filter(e -> DriverLibraryConfigTypeEnum.CLOCK_TEMPLATE.getId().equals(e.getType())).collect(Collectors.toList());
        JSONArray templateFile = packageConfigData(templateFileList,directoryList);
        List<DriverLibraryConfig> driverDocumentationFileList = configList.stream().filter(e -> DriverLibraryConfigTypeEnum.DRIVER_DOCUMENTATION.getId().equals(e.getType())).collect(Collectors.toList());
        JSONArray driverDocumentationFile = packageConfigData(driverDocumentationFileList,directoryList);
        List<DriverLibraryConfig> otherDriverFileList = configList.stream().filter(e -> DriverLibraryConfigTypeEnum.OTHER_DRIVER.getId().equals(e.getType())).collect(Collectors.toList());
        JSONArray otherDriverFile = packageConfigData(otherDriverFileList,directoryList);
        resultData.fluentPut("hHeader",hHeaderFile).fluentPut("cSource",cSourceFile).fluentPut("clockTemplate",templateFile).fluentPut("driverDocumentation",driverDocumentationFile).fluentPut("otherDriver",otherDriverFile);
        return JsonUtil.getSuccess("").fluentPut(APP.DATA, resultData);
    }

    /**
     * 组装驱动配置数据
     * @param configDataList
     * @return
     */
    public JSONArray packageConfigData(List<DriverLibraryConfig> configDataList,List<DriverLibraryDirectory> directoryList){
        JSONArray dataArray = new JSONArray();
        for (DriverLibraryConfig config : configDataList){
            JSONObject dataObject = new JSONObject();
            dataObject.put("configId",config.getConfigId());
            dataObject.put("directoryId",config.getDirectoryId());
            DriverLibraryDirectory directory = directoryList.stream().filter(e ->e.getDirectoryId().equals(config.getDirectoryId())).findFirst().orElse(null);
            dataObject.put("directoryName",directory == null ? "" : directory.getDirectoryName());
            dataArray.add(dataObject);
        }
        return dataArray;
    }

    /**
     * 添加驱动配置文件
     * @param data
     * @return
     */
    public JSONObject add(JSONObject data){
        Integer configType = data.getInteger("configType");
        Integer directoryId = data.getInteger("directoryId");
        DriverLibraryDirectory directory = driverLibraryDirectoryService.findById(directoryId);
        if (directory == null){
            return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,"找不到对应的工程目录!");
        }
        List<DriverLibraryConfig> configList = findByProperties(new String[]{"driverLibraryId","type"},new Object[]{directory.getDriverLibraryId(),configType});
        if (DriverLibraryConfigTypeEnum.H_HEADER.getId().equals(configType)){
            if (!configList.isEmpty()){
                return JsonUtil.getFail(ErrorCodeEnum.DUPLICATE_DATA,".h头文件目录已存在!");
            }
        }
        if (DriverLibraryConfigTypeEnum.C_SOURCE.getId().equals(configType)){
            if (!configList.isEmpty()){
                return JsonUtil.getFail(ErrorCodeEnum.DUPLICATE_DATA,".c源文件目录已存在!");
            }
        }
        if (DriverLibraryConfigTypeEnum.CLOCK_TEMPLATE.getId().equals(configType)){
            List<Integer> configIdList = configList.stream().map(DriverLibraryConfig::getConfigId).collect(Collectors.toList());
            if (configIdList.contains(directoryId)){
                return JsonUtil.getFail(ErrorCodeEnum.DUPLICATE_DATA,"当前文件已设置为时钟模板文件,请勿重复设置!");
            }
        }
        if (DriverLibraryConfigTypeEnum.DRIVER_DOCUMENTATION.getId().equals(configType)){
            if (!configList.isEmpty()){
                return JsonUtil.getFail(ErrorCodeEnum.DUPLICATE_DATA,"说明文档目录已存在!");
            }
        }
        if (DriverLibraryConfigTypeEnum.OTHER_DRIVER.getId().equals(configType)){
            if (!configList.isEmpty()){
                return JsonUtil.getFail(ErrorCodeEnum.DUPLICATE_DATA,"其他驱动文件目录已存在!");
            }
        }
        DriverLibraryConfig config = new DriverLibraryConfig();
        config.setDriverLibraryId(directory.getDriverLibraryId());
        config.setDirectoryId(directoryId);
        config.setType(configType);
        save(config);
        return JsonUtil.getSuccess("");
    }

    /**
     * 删除驱动配置文件
     * @param data
     * @return
     */
    public JSONObject delete(JSONObject data){
        Integer configId = data.getInteger("configId");
        DriverLibraryConfig config = findById(configId);
        if (config != null){
            removeById(configId);
        }
        return JsonUtil.getSuccess("");
    }

}
